package com.zmn.mcc.admin.controller.role;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.mcc.business.interfaces.dept.DeptBService;
import com.zmn.mcc.business.interfaces.staff.StaffBService;
import com.zmn.mcc.common.constant.RoleDict;
import com.zmn.mcc.cache.DeptCache;
import com.zmn.mcc.manager.config.MccConfig;
import com.zmn.mcc.model.entity.dept.McDept;
import com.zmn.mcc.model.entity.organize.McOrganize;
import com.zmn.mcc.model.entity.role.McRole;
import com.zmn.mcc.model.entity.role.McRoleQuery;
import com.zmn.mcc.model.entity.staff.McStaff;
import com.zmn.mcc.services.interfaces.dept.DeptService;
import com.zmn.mcc.services.interfaces.organize.OrganizeService;
import com.zmn.mcc.services.interfaces.role.RoleStaffService;
import com.zmn.mcc.services.interfaces.staff.StaffService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author heguanghua
 * @since 2020/04/15 10:53
 */
@Controller
@RequestMapping("/role/")
public class RoleListController extends RoleBaseController {

    @Resource
    private RoleStaffService roleStaffService;
    @Resource
    private DeptService deptService;
    @Resource
    private DeptBService deptBService;
    @Resource
    private StaffService staffService;
    @Resource
    private StaffBService staffBService;
    @Resource
    private DeptCache deptCache;
    @Resource
    private MccConfig config;
    @Resource
    private OrganizeService organizeService;


    /**
     * 角色列表
     */
    @RequestMapping(value = "list")
    public String list(HttpServletRequest request,
                       @ModelAttribute McRoleQuery query,
                       Model model) {

        String keyword = request.getParameter("keyword");
        if (NumberUtil.isNumber(keyword)) {
            query.setRoleId(Integer.parseInt(keyword));
            query.setRoleName("");
        } else {
            query.setRoleName(keyword);
        }

        // 如员工无"系统全局角色"，则只可见部门及下级部门拥有的角色
        List<Integer> deptIds = new ArrayList<>();

        // 员工是否拥有"系统全局角色"
        Integer staffId = getStaffId();
        boolean isGlobalAdmin = staffBService.isGlobalAdmin(staffId);
        if (!isGlobalAdmin) {
            McStaff staff = staffService.findByKey(staffId);
            if (NumberUtil.isNotNullOrZero(staff.getDeptId())) {
                deptIds = deptCache.listSuborDeptId(staff.getDeptId());
            }
            if (CollectionUtil.isNullOrEmpty(deptIds)) {
                deptIds.add(-1);
            }
        }
        query.setDeptIds(deptIds);

        List<McRole> items = roleService.listPageByQuery(query);

        model.addAttribute("items", items);
        model.addAttribute("vo", query);

        model.addAttribute("keyword", keyword);
        model.addAttribute("types", RoleDict.roleTypeMap());

        // 是否拥有"权限管理员角色"
        model.addAttribute("isAssignAdmin", staffBService.isAssignAdmin(getStaffId()));

        // 角色列表
        McRoleQuery roleQuery = new McRoleQuery();
        roleQuery.setStatus(GlobalDict.STATUS_ENABLE);
        List<McRole> mcRoles = roleService.listByQuery(roleQuery);
        model.addAttribute("roles", mcRoles);

        return "role/list";
    }

    /**
     * 角色详情
     */
    @RequestMapping("detail")
    public String detail(HttpServletRequest request,
                         @RequestParam(value = "roleId", defaultValue = "0") Integer roleId,
                         Model model) {

        McRole obj = !NumberUtil.isNullOrZero(roleId) ? roleService.findByKey(roleId) : new McRole();
        if (NumberUtil.isNullOrZero(roleId)) {
            obj.setType(RoleDict.ROLE_TYPE_INSIDE);
        }

        // 操作人
        int operatorId = getStaffId();
        McStaff operator = staffService.findByKey(operatorId);
        //int deptId = operator.getDeptId();

        // 检验操作人是否拥有"系统全局角色"、"超级管理员角色"
        boolean isGlobalAdmin = false;
        boolean isSuperAdmin = false;
        //if(NumberUtil.isNullOrZero(roleId)) {
        isGlobalAdmin = staffBService.isGlobalAdmin(operatorId);
        if (isGlobalAdmin) {
            isSuperAdmin = staffBService.isSuperAdmin(operatorId);
        }
        //}

        // 操作人部门
        int deptLevel = 0;
        if (!isGlobalAdmin && NumberUtil.isNullOrZero(roleId)) {
            if (NumberUtil.isNotNullOrZero(operator.getDeptId())) {
                McDept dept = deptService.findByKey(operator.getDeptId());
                if (dept != null) {
                    deptLevel = dept.getLevel();
                }
            }
        }

        // 角色所属部门
        McDept dept = NumberUtil.isNotNullOrZero(obj.getDeptId()) ? deptService.findByKey(obj.getDeptId()) : new McDept();

        List<McOrganize> higherOrganizeList = listHigherOrganize(dept);
        McOrganize orgOne = higherOrganizeList.size() >= 1 ? higherOrganizeList.get(higherOrganizeList.size() - 1) : new McOrganize();
        McOrganize orgTwo = higherOrganizeList.size() >= 2 ? higherOrganizeList.get(higherOrganizeList.size() - 2) : new McOrganize();
        McOrganize orgThr = higherOrganizeList.size() >= 3 ? higherOrganizeList.get(higherOrganizeList.size() - 3) : new McOrganize();
        model.addAttribute("orgOne", orgOne);
        model.addAttribute("orgTwo", orgTwo);
        model.addAttribute("orgThr", orgThr);

        model.addAttribute("obj", obj);
        model.addAttribute("dept", dept);

        model.addAttribute("operator", operator);
        model.addAttribute("isSuperAdmin", isSuperAdmin);
        model.addAttribute("isGlobalAdmin", isGlobalAdmin);
        //model.addAttribute("deptId", deptId);
        model.addAttribute("deptLevel", deptLevel);

        model.addAttribute("exportLimit", config.getDataExportLimit());
        model.addAttribute("dayLimit", config.getDataDayLimit());

        model.addAttribute("types", RoleDict.roleTypeMap());

        // 是否拥有"权限管理员角色"
        model.addAttribute("isAssignAdmin", staffBService.isAssignAdmin(getStaffId()));

        return "role/detail";
    }

    /**
     * 查询当前部门的所有上级组织，越上级越在列表的后面
     *
     * @param dept 当前部门
     * @return
     */
    private List<McOrganize> listHigherOrganize(McDept dept) {
        // 当前部门不属于任何组织
        if (NumberUtil.isNullOrZero(dept.getOrgId())) {
            return new ArrayList<>(0);
        }

        List<McOrganize> highers = new ArrayList<>();

        // 一直找到所有的上级组织
        Integer current = dept.getOrgId();
        while (true) {
            McOrganize organize = organizeService.findByKey(current);
            if (Objects.isNull(organize)) {
                break;
            }
            highers.add(organize);
            if (Objects.equals(GlobalConsts.TOP_ID, organize.getParentId())) {
                break;
            }
            current = organize.getParentId();
        }

        return highers;
    }

}
